package com.pangu.interfaces.proxy;

import com.pangu.exception.api.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.proxy.InvocationHandler;
import org.springframework.cglib.proxy.Proxy;

import java.lang.reflect.Method;

/**
 * @author Linbizhao
 * @description: 盘古降级代理创建者
 * @since 2023/11/17
 */
@Slf4j
@SuppressWarnings("ALL")
public class FallbackProxyCreator<T> {

    protected volatile T proxy;

    public T getProxy(Class<T> clazz) {
        if (proxy == null) {
            synchronized (this) {
                if (proxy == null) {
                    Class[] interfaces;
                    if (clazz.isInterface()) {
                        interfaces = new Class[]{clazz};
                    } else {
                        interfaces = clazz.getInterfaces();
                    }
                    try {
                        proxy = (T) Proxy.newProxyInstance(clazz.getClassLoader(), interfaces, new FallbackProxy());
                    } catch (Exception e) {
                        log.error(e.getMessage(), e);
                        log.warn("{} 类采用spring的cglib生成动态代理失败，重新采用java 原生的动态代理处理", clazz.getName());
                        proxy = (T) java.lang.reflect.Proxy.newProxyInstance(clazz.getClassLoader(), interfaces, new FallbackProxy());
                    }
                    log.info("{} 类使用动态代理生成具体实现", clazz.getName());
                }
            }
        }
        return proxy;
    }

    static class FallbackProxy implements InvocationHandler, java.lang.reflect.InvocationHandler {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            log.error("调用pangu服务 [{}] 接口的 [{}] 方法失败, param:{}", method.getDeclaringClass().getName(), method.getName(), args);
            return ApiResponse.fail("调用pangu服务方法失败!");
        }
    }
}
